import { logMgr } from "../Manager/LogMgr"
import { ViewMaskBlock, ViewMaskBlockType, viewMgr, ViewTweenType } from "../Manager/ViewMgr"
import { BaseView } from "./BaseView"
import { CycleLifeFlag } from "./CycleLifeFlag"

/**
 * 生命周期
 * onPreShow 打开动画开始前触发 通常在这里处理界面业务逻辑初始化
 * onClickEventInit
 * onCustomEventInit 
 * onShow 打开动画完成后触发
 * onCloseBegin 关闭动画开始前触发 通常在这里处理界面关闭时的业务逻辑
 * onCloseEnd 关闭动画完成后触发
 * onRefreshUI 界面隐藏-显示时触发
 */


export abstract class BasePop extends BaseView {

    protected abstract onPreShow(): void;

    // 是否全屏界面 用于隐藏层级下面界面
    private _fullScreen: boolean = true
    set FullScreen(b: boolean) { this._fullScreen = b }
    get FullScreen() { return this._fullScreen }

    // 界面ID
    private _viewName: string = null
    set ViewName(id: string) { this._viewName = id }
    get ViewName() { return this._viewName }

    private tweenType = ViewTweenType.ScaleAnim
    private _param: any = null

    //////////////////////////////////////////////////////框架调用
    public readonly init = (param: any, tween: ViewTweenType, mask: ViewMaskBlockType) => {
        if (this.checkCycleLifeFlag(CycleLifeFlag.PreLoad)) return
        this.setCycleLifeFlag(CycleLifeFlag.PreLoad)
        this.node.opacity = 0
        this._param = param
        this.tweenType = tween || ViewTweenType.ScaleAnim
        this.createMask(mask)
    }

    public readonly dispose = (tween: ViewTweenType) => {
        if (this.checkCycleLifeFlag(CycleLifeFlag.Closing)) return
        this.setCycleLifeFlag(CycleLifeFlag.Closing)
        this.tweenType = tween || ViewTweenType.ScaleAnim
        this.onCloseBegin()
        this.closeAction()
    }

    public readonly reshow = () => {
        this.onRefreshUI()
    }

    //////////////////////////////////////////////////////重载引擎内置方法
    protected readonly onLoad = () => { }
    protected readonly onDestroy = () => {
        // 不做处理了 在 readyDestroy 处理
        !this.checkCycleLifeFlag(CycleLifeFlag.Destroy) && logMgr.error(`[${this.name}] CycleAlive is true when onDestroy called`)
    }

    protected readonly start = async () => {
        if (this.checkCycleLifeFlag(CycleLifeFlag.Opening)) return
        this.setCycleLifeFlag(CycleLifeFlag.Opening)

        // @ts-ignore
        while (cc._widgetManager._nodesOrderDirty) {
            await this.delay()
        }
        this.node.opacity = 255
        this.onPreShow()
        this.onClickEventInit()
        this.onCustomEventInit()
        this.openAction()
    }


    //////////////////////////////////////////////////////重新定义生命周期
    protected onClickEventInit() { }
    protected onCustomEventInit() { }
    protected onShow() { }
    protected onCloseBegin() { }
    protected onCloseEnd() { }
    protected onRefreshUI() { }

    private openAction() {
        if (this.tweenType == ViewTweenType.ScaleAnim) {
            let origitScale = this.node.scale
            this.node.scale = 0.1
            cc.tween(this.node)
                .to(0.2, { scale: origitScale })
                .call(() => {
                    this.readyShow()
                })
                .start();
        } else {
            this.readyShow();
        }
    }

    private readyShow() {
        if (this.checkCycleLifeFlag(CycleLifeFlag.Show)) return
        this.setCycleLifeFlag(CycleLifeFlag.Show)
        this.onShow();
    }

    private closeAction() {
        if (this.tweenType == ViewTweenType.ScaleAnim) {
            let scale = this.node.scale + 0.1;
            cc.tween(this.node)
                .to(0.1, { scale: scale })
                .to(0.1, { scale: 0 })
                .call(() => {
                    this.readyDestroy()
                })
                .start();
        } else {
            this.readyDestroy()
        }
    }

    private readyDestroy() {
        if (this.checkCycleLifeFlag(CycleLifeFlag.Destroy)) return
        this.setCycleLifeFlag(CycleLifeFlag.Destroy)
        this.onCloseEnd();
        this.onDispose()
        this.node.destroy()
    }

    //////////////////////////////////////////////////////遮罩
    static spriteFrame: cc.SpriteFrame = null
    private createMask(mask: ViewMaskBlockType) {
        if (mask == ViewMaskBlockType.None) return

        if (!BasePop.spriteFrame) {
            let texture = new cc.Texture2D()
            texture.initWithData(Uint8Array.from([0, 0, 0, 128]), cc.Texture2D.PixelFormat.RGBA8888, 1, 1)
            let spriteFrame = new cc.SpriteFrame()
            spriteFrame.setTexture(texture)
            BasePop.spriteFrame = spriteFrame
        }
        let maskNode = new cc.Node()
        maskNode.name = "ViewMaskNode"
        maskNode.setContentSize(5000, 5000)
        if (mask & ViewMaskBlock.Mask) {
            let sp = maskNode.addComponent(cc.Sprite)
            sp.spriteFrame = BasePop.spriteFrame
            sp.sizeMode = cc.Sprite.SizeMode.CUSTOM
            maskNode.opacity = 100
        }
        if (mask & ViewMaskBlock.Block) {

        }
        if (mask & ViewMaskBlock.Close) {
            maskNode.on('click', () => {
                this.onCloseClick()
            })
        }
        this.node.addChild(maskNode, -1)
    }

    //////////////////////////////////////////////////////通用方法    
    protected onCloseClick() {
        this.checkCycleLifeFlag(CycleLifeFlag.Show) && viewMgr.closeView(this.ViewName)
    }
}
